/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.yonsei.iwb.srf;

import com.hp.hpl.jena.vocabulary.RDF;
import edu.yonsei.iwb.di.ESService;
import edu.yonsei.iwb.sdt.SDTLearner;
import edu.yonsei.iwb.sdt.datastructure.TargetInstance;
import edu.yonsei.iwb.ts.TSSearch;
import edu.yonsei.iwb.ts.model.ObjectNode;
import edu.yonsei.iwb.ts.model.Triple;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Random;

/**
 *
 * @author dk
 */
public class TIBootstrapper {

    private String targetClass;
    private String targetProperty;
    private int valueSize;
    
    /**
     * index : ID, value : TI Name
     */
    private ArrayList<String> tiList; //<ID,TIName>
    
    /**
     * key : ID, value : class value
     */
    private Hashtable<Integer, String> tcrvTable; //<ID,Value>
    private ArrayList<String> valueList;

    @Deprecated
    public TIBootstrapper(String[] indexName, String tc, String tp) throws IOException {
        ESService di = new ESService();
        TSSearch ts = new TSSearch(indexName);
        this.targetClass = tc;
        this.targetProperty = tp;
        this.tcrvTable = new Hashtable();
        this.tiList = new ArrayList();
        this.valueList = new ArrayList();
//        File f = new File("./input.csv");
//        if(f.exists()){
//            generateTIValueTable(true);            
//        }else{
            generateTIValueTable();
//        }
        this.valueSize = this.valueList.size();        
    }
    
    public TIBootstrapper(String[] indexName, String dir) throws IOException {        
        this.tcrvTable = new Hashtable();
        this.tiList = new ArrayList();
        this.valueList = new ArrayList();
        generateTIValueTable(dir);
        this.valueSize = this.valueList.size();
    }
    
    public TIBootstrapper(String dir) throws IOException {        
        this.tcrvTable = new Hashtable();
        this.tiList = new ArrayList();
        this.valueList = new ArrayList();
        generateTIValueTable(dir);
        this.valueSize = this.valueList.size();
    }
    
    /**
     * @param treeSize the number of slave
     * @return
     */
    public ArrayList<Hashtable<Integer,ArrayList<String>>> getInstanceListOfEachSlave(int treeSize) {
        ArrayList<Hashtable<Integer,ArrayList<String>>> tiset = new ArrayList();
        
        for (int i = 0; i < treeSize; i++) {
            Hashtable<Integer,ArrayList<String>> sltiset = new Hashtable();
            for (int j = 0; j < valueSize; j++) {
                ArrayList<String> instlist = new ArrayList<String>();                
                sltiset.put(j, instlist);                
            }
            
            for (int j = 0; j < this.tiList.size(); j++) {
                String classValue = this.tcrvTable.get(j);
                int value = getClassValue(classValue);
                ArrayList<String> tis = sltiset.get(value);
                tis.add(this.tiList.get(j));
            }
            
            tiset.add(sltiset);            
        }
        return tiset;
    }

    /**
     *
     * @param treeSize the number of slave
     * @param tiSize the number of target instance
     * @return
     */
    public ArrayList<Hashtable<Integer,ArrayList<String>>> getInstanceListOfEachSlave(int treeSize, int tisize) {
        ArrayList<Hashtable<Integer,ArrayList<String>>> tiset = new ArrayList();
        Random seedOfseed = new Random();
        for (int i = 0; i < treeSize; i++) {
            Hashtable<Integer,ArrayList<String>> sltiset = new Hashtable();
            for (int j = 0; j < valueSize; j++) {
                sltiset.put(j, new ArrayList<String>());
            }
            
            int seed = seedOfseed.nextInt();
            Random random = new Random(seed);            
            int size = (tisize/valueSize);            //value간의 비율을 맞추기 위해서
            int current = 0;
            
//            System.out.println("# Starting ti value generation...");                        
            while(true){
                int index = random.nextInt(tiList.size());
                String vv = this.tcrvTable.get(index);
                int value = getClassValue(vv);
//                if(value == 100){
//                    continue;
//                }
                ArrayList<String> tis = sltiset.get(value);
                if(tis.size() < size+1){
                    String subject = this.tiList.get(index);
                    tis.add(subject);
//                    System.out.println("# "+subject+" - " +value);
                    current++;
                }
                
                if(tisize < current){
                    break;
                }
            }
            
            tiset.add(sltiset);
            
        }
//        System.out.println("# finished");
        
        return tiset;
    }
    
    private int getClassValue(String vv){
        return this.valueList.indexOf(vv);
    }
           
//    private int getClassValue(String vv){
//        int value = Integer.parseInt(vv);
//        if (value < 2) {
//            return 0;
//        } else if (value >= 2 && value < 8) {
//            return 1;
//        } else if (value >= 8 && value < 13) {
//            return 2;
//        } else if (value >= 13 && value < 28) {
//            return 3;
//        } else {
//            return 100;
//        }        
//    }
    
    
    public void write(Hashtable<String, Integer> tilist) throws UnsupportedEncodingException, FileNotFoundException, IOException {
        File file = new File("./inputdata4.tsv");
        PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), "euc-kr"));
//        pw.write("contract_id\tnumberOftenders\tprice\tcountry\tregion\tlocal_address\n");
        BufferedReader tiReader = new BufferedReader(new InputStreamReader(new FileInputStream("./contracts.txt"), "euc-kr"));
        String con;
        while ((con = tiReader.readLine()) != null) {
//            String con = contracts.get(i);


            pw.flush();
        }
        pw.close();
    }
    
    private void generateTIValueTable(boolean flag) throws IOException {
        System.out.println("# Target Instance and value generating start...");
        BufferedReader tiReader = new BufferedReader(new InputStreamReader(new FileInputStream("./input.csv"), "euc-kr"));
        String row;
        while ((row = tiReader.readLine()) != null) {
            String[] rowvalues = row.split(",");
            int key = Integer.parseInt(rowvalues[0]);
            String su = rowvalues[1];            
            String value = rowvalues[2];
            this.tiList.add(su);            
//            System.out.println(key+" = "+value);
            this.tcrvTable.put(key, value);
            if(!this.valueList.contains(value)){
                this.valueList.add(value);
            }
        }       
        System.out.println("finished");
    }  
    
    private void generateTIValueTable() throws IOException {
        File file = new File("./input.csv");
        PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), "euc-kr"));
        
        System.out.println("# Target Instance and value generating start...");
        ArrayList<Triple> obset = TSSearch.listTriple(null, targetProperty, null);
//        System.out.println("--"+obset.size());
        for (int i = 0; i < obset.size(); i++) {
            Triple triple = obset.get(i);
            String su = triple.getSubject();
            if(!this.tiList.contains(su)){
                this.tiList.add(su);
                int key = this.tiList.indexOf(su);
                String value = triple.getObject().getValue();
                this.tcrvTable.put(key, value);
                
                if(!this.valueList.contains(value)){
                    this.valueList.add(value);
                }
                
                pw.write(key+","+su+","+value+"\n");
            }            
        }
        pw.flush();
        pw.close();
        System.out.println("finished");
    }
    
    
    /**
     * data parition version
     * @throws IOException 
     */
    private void generateTIValueTable(String dir) throws IOException {
                
//        System.out.println("# Target Instance and value generating start...");
        
        File testf = new File("./dataset/" + dir + "/training.tsv");
        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(testf), "euc-kr"));
        String line = null;
        while ((line = br.readLine()) != null) {
            String[] s = line.split("\t");
            String su = s[0];
            String value = s[1];            
            this.tiList.add(su);
            int key = this.tiList.indexOf(su);            
            this.tcrvTable.put(key, value);
//            if(!this.valueList.contains(value)){
//                this.valueList.add(value);
//            }            
        }
        
        
        File vlist = new File("./dataset/" + dir + "/vlist.tsv");
        BufferedReader br2 = new BufferedReader(new InputStreamReader(new FileInputStream(vlist), "euc-kr"));
        String line2 = null;
        while ((line2 = br2.readLine()) != null) {
            String[] s = line2.split("\t");
            String su = s[0];
            int value = Integer.parseInt(s[1]);
            this.valueList.add(value, su);
        }                
    }
    
}
